package com.sky.service.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.vo.*;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;



@Service
public class ReportServiceImpl implements ReportService {


    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private WorkspaceService workspaceService;

    /**
     * 营业额统计
     * @param begin
     * @param end
     * @return
     */
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end){
        //查询日期 ，拼接
        List<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);
        while(!begin.equals(end)){
            begin = begin.plusDays(1);
            dateList.add(begin);
        }
        //2.查询每天的营业额
        List<Double> moneyList = new ArrayList<>();
        for(LocalDate date : dateList){
            LocalDateTime begin_time = LocalDateTime.of(date,LocalDateTime.MIN.toLocalTime());
            LocalDateTime end_time = LocalDateTime.of(date,LocalDateTime.MAX.toLocalTime());
            Map<String,Object> map = new HashMap<>();
            map.put("begin_time",begin_time);
            map.put("end_time",end_time);
            map.put("status", Orders.COMPLETED);
            Double total_price = orderMapper.calculateMoney(map);
            total_price = total_price == null ?  0.0:total_price;
            moneyList.add(total_price);
        }
        return TurnoverReportVO.builder()
                .dateList(StringUtils.join(dateList,","))
                .turnoverList(StringUtils.join(moneyList,","))
                .build();
    }

    /**
     * 用户统计
     * @param begin
     * @param end
     * @return
     */
    public UserReportVO userStatistics(LocalDate begin, LocalDate end){
        List<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);
        while(!begin.equals(end)){
            begin = begin.plusDays(1);
            dateList.add(begin);
        }
        List<Integer> totalUserList = new ArrayList<>();
        List<Integer> increaseUserList = new ArrayList<>();
        for(LocalDate date : dateList){
            LocalDateTime begin_time = LocalDateTime.of(date,LocalDateTime.MIN.toLocalTime());
            LocalDateTime end_time = LocalDateTime.of(date,LocalDateTime.MAX.toLocalTime());
            Integer cur_user = userMapper.userStatistics(null,end_time);
            totalUserList.add(cur_user);
            Integer increaseUser = userMapper.userStatistics(begin_time,end_time);
            increaseUserList.add(increaseUser);
        }
        return UserReportVO.builder()
                .dateList(StringUtils.join(dateList,","))
                .newUserList(StringUtils.join(increaseUserList,","))
                .totalUserList(StringUtils.join(totalUserList,","))
                .build();
    }

    /**
     * 订单统计
     * @param begin
     * @param end
     * @return
     */
    public OrderReportVO orderStatistics(LocalDate begin, LocalDate end){
        List<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);
        while(!begin.equals(end)){
            begin = begin.plusDays(1);
            dateList.add(begin);
        }
        List<Integer> curOrderList = new ArrayList<>();
        List<Integer> validOrderCountList = new ArrayList<>();
        Integer totalOrderCount = Integer.valueOf(0);
        Integer validOrderCount = Integer.valueOf(0);
        for(LocalDate date : dateList){
            LocalDateTime begin_time = LocalDateTime.of(date,LocalDateTime.MIN.toLocalTime());
            LocalDateTime end_time = LocalDateTime.of(date,LocalDateTime.MAX.toLocalTime());
            Integer cur_order = orderMapper.orderStatistics(begin_time,end_time,null);
            curOrderList.add(cur_order);
            totalOrderCount += cur_order;
            Integer validOrder = orderMapper.orderStatistics(begin_time,end_time,Orders.COMPLETED);
            validOrderCountList.add(validOrder);
            validOrderCount += validOrder;
        }
        Double orderCompletionRate = Double.valueOf(validOrderCount)/Double.valueOf(totalOrderCount);
        return OrderReportVO.builder()
                .dateList(StringUtils.join(dateList,","))
                .orderCountList(StringUtils.join(curOrderList,","))
                .validOrderCountList(StringUtils.join(validOrderCountList,","))
                .totalOrderCount(totalOrderCount)
                .validOrderCount(validOrderCount)
                .orderCompletionRate(orderCompletionRate)
                .build();
    }

    /**
     * 销量top10菜品统计
     * @return
     */
    public SalesTop10ReportVO top10Statistics(LocalDate begin, LocalDate end){
        LocalDateTime begin_time = LocalDateTime.of(begin,LocalDateTime.MIN.toLocalTime());
        LocalDateTime end_time = LocalDateTime.of(end,LocalDateTime.MAX.toLocalTime());
        List<GoodsSalesDTO> goodsSalesDTOList = orderMapper.getSalesTop10(begin_time,end_time);
        StringBuilder nameList = new StringBuilder();
        StringBuilder number = new StringBuilder();
        for(int i = 0;i < goodsSalesDTOList.size();i++){
            GoodsSalesDTO goodsSalesDTO = goodsSalesDTOList.get(i);
            nameList.append(goodsSalesDTO.getName());
            number.append(goodsSalesDTO.getNumber());
            if(i != goodsSalesDTOList.size() - 1){
                nameList.append(",");
                number.append(",");
            }
        }
        return SalesTop10ReportVO.builder()
                .nameList(nameList.toString())
                .numberList(number.toString())
                .build();
    }

    /**
     * 导出运营数据报表
     */
    public void exportBussinessData(HttpServletResponse httpServletResponse){
        //1.查询营业额数据
        LocalDate date = LocalDate.now().minusDays(1);
        LocalDate date2 = LocalDate.now().minusDays(30);
        LocalDateTime begin = LocalDateTime.of(date2,LocalDateTime.MIN.toLocalTime());
        LocalDateTime end = LocalDateTime.of(date,LocalDateTime.MAX.toLocalTime());
        BusinessDataVO businessData = workspaceService.getBusinessData(begin, end);

        //2.通过poi将数据写入到excel文件中
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        try {
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            XSSFSheet sheet1 = workbook.getSheet("sheet1");
            XSSFRow row = sheet1.getRow(1);
            row.getCell(1).setCellValue("时间"+date+"至"+date2);
            XSSFRow row3 = sheet1.getRow(3);
            row3.getCell(2).setCellValue(businessData.getTurnover());
            row3.getCell(4).setCellValue(businessData.getOrderCompletionRate());
            row3.getCell(6).setCellValue(businessData.getNewUsers());
            XSSFRow row4 = sheet1.getRow(4);
            row4.getCell(2).setCellValue(businessData.getValidOrderCount());
            row4.getCell(4).setCellValue(businessData.getUnitPrice());
            for(int i= 0;i<30;i++){
                //1.查询每一天的营业额
                LocalDate curDay = date2.plusDays(i);
                begin = LocalDateTime.of(curDay,LocalDateTime.MIN.toLocalTime());
                end = LocalDateTime.of(curDay,LocalDateTime.MAX.toLocalTime());
                //2.获得每一行
                XSSFRow row1 = sheet1.getRow(i+7);
                businessData = workspaceService.getBusinessData(begin, end);
                row1.getCell(1).setCellValue(curDay.toString());
                row1.getCell(2).setCellValue(businessData.getTurnover());
                row1.getCell(3).setCellValue(businessData.getValidOrderCount());
                row1.getCell(4).setCellValue(businessData.getOrderCompletionRate());
                row1.getCell(5).setCellValue(businessData.getUnitPrice());
                row1.getCell(6).setCellValue(businessData.getNewUsers());

            }
            //3.通过输出流将excel下载至客户端浏览器
            ServletOutputStream outputStream = httpServletResponse.getOutputStream();
            workbook.write(outputStream);

            //关闭资源
            workbook.close();
            outputStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}
